package org.hepeng.workx.util;

import net.openhft.compiler.CompilerUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.hepeng.workx.exception.ApplicationRuntimeException;
import org.springframework.core.GenericTypeResolver;
import org.springframework.util.Assert;

import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author he peng
 */
public class ClassUtils {

    public static boolean hasClass(String className) {
        Class<?> clazz;
        try {
            clazz = org.apache.commons.lang3.ClassUtils.getClass(className);
        } catch (ClassNotFoundException e) {
            return false;
        }
        return Objects.nonNull(clazz);
    }

    public static boolean isAbstract(Class<?> clazz) {
        Assert.notNull(clazz , "clazz must not be null");
        if (Modifier.isAbstract(clazz.getModifiers())) {
            return true;
        }

        return false;
    }

    public static Class<?> getSingleGeneric(Class<?> clazz , Class<?> genericIfc) {
        Assert.notNull(clazz , "clazz must not be null");
        Assert.notNull(genericIfc , "genericIfc must not be null");
        return GenericTypeResolver.resolveTypeArgument(clazz , genericIfc);
    }

    @Deprecated
    public static Class compileFromJavaCode(String qualifiedClassName , String javaCode) {
        Assert.hasLength(qualifiedClassName , "qualifiedClassName must not be blank");
        Assert.hasLength(javaCode , "javaCode must not be blank");
        try {
            ClassLoader classLoader = ClassLoader.getSystemClassLoader();
            if (Objects.isNull(classLoader)) {
                classLoader = Thread.currentThread().getContextClassLoader();
            }
            return compileFromJavaCode(classLoader , qualifiedClassName , javaCode);
        } catch (Throwable t) {
            throw new ApplicationRuntimeException("compile java code error : " + t.getMessage() , t);
        }
    }

    @Deprecated
    public static Class compileFromJavaCode(ClassLoader classLoader , String qualifiedClassName , String javaCode) {
        Assert.notNull(classLoader , "classLoader must not be null");
        Assert.hasLength(qualifiedClassName , "qualifiedClassName must not be blank");
        Assert.hasLength(javaCode , "javaCode must not be blank");
        try {
            return CompilerUtils.CACHED_COMPILER.loadFromJava(classLoader , qualifiedClassName, javaCode);
        } catch (Throwable t) {
            throw new ApplicationRuntimeException("compile java code error : " + t.getMessage() , t);
        }
    }

    public static boolean isInterface(Class targetClass) {
        Assert.notNull(targetClass , "targetClass must not be null");
        return Modifier.isInterface(targetClass.getModifiers());
    }
}
